home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / qtools0.2-src.lha / src / libqdisplay / draw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-11  |  3.9 KB  |  166 lines

  1. #define    LIBQDISPLAY_CORE
  2. #include "../include/libqdisplay.h"
  3.  
  4. /*
  5.  *   Render a Quake polygon:
  6.  *      read it from the db
  7.  *      transform it into 3d
  8.  *      clip it in 3d
  9.  *      compute the 2d texture gradients
  10.  *      scan convert
  11.  *      pass off the spans
  12.  */
  13.  
  14. /* drawing */
  15. displaypointer texture;
  16. int textureRow;
  17. int textureMask1, textureMask2;
  18. short int textureShift1, textureShift2;
  19. short int textureMip;
  20. short int textureType;
  21. unsigned char textureColor;
  22.  
  23. #ifndef __OPTIMIZE__
  24. #include "draw-orig.c"
  25. #else
  26. #include "draw-opti.c"
  27. #endif
  28.  
  29. static inline void draw_poly(int n, point_3d ** vl)
  30. {
  31.   int i, j, y, ey;
  32.   fix ymin, ymax;
  33.  
  34.   /* find max and min y height */
  35.   ymin = ymax = vl[0]->sy;
  36.   for (i = 1; i < n; ++i) {
  37.     if (vl[i]->sy < ymin)
  38.       ymin = vl[i]->sy;
  39.     else if (vl[i]->sy > ymax)
  40.       ymax = vl[i]->sy;
  41.   }
  42.  
  43.   /* scan out each edge */
  44.   j = n - 1;
  45.   for (i = 0; i < n; ++i) {
  46.     scan_convert(vl[i], vl[j]);
  47.     j = i;
  48.   }
  49.  
  50.   y = FIX_INT(ymin);
  51.   ey = FIX_INT(ymax);
  52.  
  53. #ifndef __OPTIMIZE__
  54.   for (; y < ey; y++) {
  55.     int sx = FIX_INT(scan[y][0]);
  56.     int ex = FIX_INT(scan[y][1]);
  57.  
  58.     if (ex - sx) {
  59.       /* iterate over all spans and draw */
  60. #ifdef DRIVER_8BIT
  61.       if (localDim.frameDepth <= 8) {
  62.     if (displayType == DISPLAY_TEXTURED)
  63.       draw_spans8(y, sx, ex);
  64.     else if (displayType == DISPLAY_FLAT)
  65.       draw_spans8flat(y, sx, ex);
  66.     else if (displayType == DISPLAY_WIRE)
  67.       draw_spans8wire(y, sx, ex);
  68.       }
  69.       else
  70. #endif
  71. #ifdef DRIVER_16BIT
  72.       if (localDim.frameDepth <= 16)
  73.     draw_spans16(y, sx, ex);
  74.       else
  75. #endif
  76. #ifdef DRIVER_24BIT
  77.       if (localDim.frameDepth <= 24)
  78.     draw_spans24(y, sx, ex);
  79.       else
  80. #endif
  81. #ifdef DRIVER_32BIT
  82. #endif
  83.     ;
  84.     }
  85.   }
  86. #else
  87.   /* iterate over all spans and draw */
  88. #ifdef DRIVER_8BIT
  89.   if (localDim.frameDepth <= 8)
  90.     if (displayType == DISPLAY_TEXTURED)
  91.       draw_spans8(y, ey);
  92.     else if (displayType == DISPLAY_FLAT)
  93.       draw_spans8flat(y, ey);
  94.     else if (displayType == DISPLAY_WIRE)
  95.       draw_spans8wire(y, ey);
  96.   else
  97. #endif
  98. #ifdef DRIVER_16BIT
  99.   if (localDim.frameDepth <= 16)
  100.     draw_spans16(y, ey);
  101.   else
  102. #endif
  103. #ifdef DRIVER_24BIT
  104.   if (localDim.frameDepth <= 24)
  105.     draw_spans24(y, ey);
  106.   else
  107. #endif
  108. #ifdef DRIVER_32BIT
  109. #endif
  110.     ;
  111. #endif
  112. }
  113.  
  114. void draw_face(__memBase, int face)
  115. {
  116.   int n = bspMem->shared.quake1.dfaces[face].numedges;
  117.   int se = bspMem->shared.quake1.dfaces[face].firstedge;
  118.   int i, edge, codes_or = 0, codes_and = 0xff;
  119.   point_3d **vlist;
  120.  
  121.   for (i = 0; i < n; ++i) {
  122.     edge = bspMem->shared.quake1.dsurfedges[se + i];
  123.  
  124.     if (edge < 0)
  125.       transform_point(&defaultPoints[i], (vec_t *) & bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[-edge].v[1]].point);
  126.     else
  127.       transform_point(&defaultPoints[i], (vec_t *) & bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[edge].v[0]].point);
  128.  
  129.     codes_or |= defaultPoints[i].ccodes;
  130.     codes_and &= defaultPoints[i].ccodes;
  131.   }
  132.  
  133.   if (codes_and)
  134.     return;
  135.   if (codes_or)                            /* poly crosses frustrum, so clip it */
  136.     n = clip_poly(n, defaultVList, codes_or, &vlist);
  137.   else
  138.     vlist = defaultVList;
  139.  
  140.   /*
  141.    * with this texChange-technique it is possible for example
  142.    * to let light render the bsp-tree, then light marks the
  143.    * last processed face as changed and render the tree again
  144.    * and voila, everything is unchanged but the new lightface
  145.    */
  146.   if (n) {
  147.     struct texture *Text;
  148.  
  149.     Text = GetCache(bspMem, face);
  150.  
  151.     if ((textureMip = compute_mip_level(bspMem, face)) != Text->lastMip)    /* if the mipmap changes, the tex and it lights changes too */
  152.       Text->texChanged = TRUE;
  153.  
  154.     GetTMap(bspMem, Text, textureMip);                /* GetTMap must have the capability to set texChange */
  155.     compute_texture_gradients(bspMem, Text, textureMip);
  156.     draw_poly(n, vlist);
  157.  
  158.     Text->lastMip = textureMip;                    /* set last mip here, perhaps GetTMap should use the old value */
  159.  
  160.     /*
  161.      * should we free the whole face if it is an ANIM_MIPMAP?
  162.      * perhaps the sizes etc. changes ...
  163.      */
  164.   }
  165. }
  166.